package com.vcredit.creditcat.service.product;

import io.netty.util.internal.StringUtil;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.vcredit.creditcat.bean.SpringContextHolder;
import com.vcredit.creditcat.dto.creditrepository.ItemStatusDto;
import com.vcredit.creditcat.dto.product.ProductApplyResultDto;
import com.vcredit.creditcat.dto.product.ProductExpireItemDto;
import com.vcredit.creditcat.enumtype.MerchantProductEnum;
import com.vcredit.creditcat.enumtype.SmsDescEnum;
import com.vcredit.creditcat.manager.SMSMessageManager;
import com.vcredit.creditcat.model.Cust;
import com.vcredit.creditcat.model.CustAccount;
import com.vcredit.creditcat.model.CustProductApply;
import com.vcredit.creditcat.model.CustProductApplyRecord;
import com.vcredit.creditcat.model.CustSupplementItem;
import com.vcredit.creditcat.model.MerchantProduct;
import com.vcredit.creditcat.model.ProductEnum;
import com.vcredit.creditcat.service.CustAccountService;
import com.vcredit.creditcat.service.CustCreditRepositoryService;
import com.vcredit.creditcat.service.CustProductApplyRecordService;
import com.vcredit.creditcat.service.CustProductApplyService;
import com.vcredit.creditcat.service.CustService;
import com.vcredit.creditcat.service.CustSupplementItemService;
import com.vcredit.creditcat.service.MerchantProductService;
import com.vcredit.creditcat.service.ProductEnumService;
import com.vcredit.creditcat.service.auth.AuthItemExtService;
import com.vcredit.creditcat.service.product.shared.ProductApplyServiceAdaptor;
import com.vcredit.creditcat.service.product.util.EnumExtUtil;
import com.vcredit.creditcat.util.ConcurrentDateUtil;
import com.vcredit.creditcat.util.Utility;
import com.vcredit.creditcat.vo.AuthItemCheckResultVo;
import com.vcredit.creditcat.vo.ProductApplyResultVo;
import com.vcredit.framework.annotation.Log;
import com.vcredit.framework.exception.BaseException;
import com.vcredit.framework.util.BeanUtil;
import com.vcredit.framework.util.JacksonUtil;

@Service
public class CreditProductService extends ProductApplyServiceAdaptor {

	private static final Logger LOG = LoggerFactory.getLogger(CreditProductService.class);

	@Autowired
	private MerchantProductService merchantProductService;
	@Autowired
	private AuthItemExtService authItemExtService;
	@Autowired
	private CustCreditRepositoryService repositoryService;
	@Autowired
	private CustProductApplyService custProductApplyService;
	@Autowired
	private CustProductApplyRecordService custProductApplyRecordService;
	@Autowired
	private ProductEnumService productEnumService;
	@Autowired
	private CustAccountService custAccountService;
	@Autowired
	private CustSupplementItemService custSupplementItemService;	
	@Autowired
	public SMSMessageManager sMSMessageManager;	
	@Autowired
	private CustService custService;	
	@Autowired
	public CreditCommonApplyService creditCommonApplyService;
	/**
	 * 产品申请额度提交
	 * 
	 * @throws Exception
	 */
	@Log
	public ProductExpireItemDto applyCommit(Long custId, Long productId, Map<String, String> otherParams)
			throws Exception {
		IProductApplyService applyService = this.getProductApplyService(productId);
		Object applyCommit = applyService.applyCommit(custId, productId, otherParams);
		if (null != applyCommit) {
			return new ProductExpireItemDto(2, productId);
		}
		return new ProductExpireItemDto(1, productId);
	}

	private IProductApplyService getProductApplyService(Long productId) throws Exception {
		MerchantProduct merchantProduct = merchantProductService.findById(productId);
		MerchantProductEnum productEnumByName = EnumExtUtil.getEnumOnValue(MerchantProductEnum.class,
				merchantProduct.getProductName(), "name");
		return (IProductApplyService) SpringContextHolder.getBean(productEnumByName.name());
	}

	/**
	 * 产品申请主方法
	 * 
	 * @author zhaoqi01
	 * @param custId
	 * @param productId
	 * @param otherParams
	 * @return
	 * @throws Exception
	 */
	@Log
	@Transactional
	public ProductApplyResultDto apply(Cust cust, long productId,Map<String, Object> otherParams,
			List<CustSupplementItem> custSupplementItemList,
			List<ItemStatusDto> itemStatusDtoList) throws Exception {
		try {
			// 1、校验认证项是否都完成、校验认证项是否过期
			AuthItemCheckResultVo authItemCheckResult = authItemExtService.getCheckResultByCustAndProduct(cust,productId,custSupplementItemList,itemStatusDtoList);
			if(authItemCheckResult.getCode() != 1) { // 不为1表示认证项校验没通过
				if(authItemCheckResult.getCode() == 5) {
					// 如果有失效的认证项，需要将失效的认证项重置
					this.handlerExpireForAuthItemCheckResult(authItemCheckResult,cust);
				}
				return new ProductApplyResultDto(2, productId);
			}
			
			// 2、校验产品是否可以再次申请
			boolean canApplyAgain = custProductApplyService.checkProductApply(cust.getCustId(), productId);
			if(!canApplyAgain) { // 不能再次申请
				return new ProductApplyResultDto(1,productId);
			}
			
			// 封装其他参数
			this.packageOtherParams(otherParams, cust, productId);
			
			// 3、产品申请
			ProductApplyResultVo applyResult = this.getProductApplyServiceImpl(productId)
					.apply(authItemCheckResult.getCustAuthInfoMap(), authItemCheckResult.getCustSupplementItemMap(), otherParams);
			
			// 4、处理申请结果
			this.handlerProductApplyResult(applyResult,cust,productId);
			
			// 5、返回
			return new ProductApplyResultDto(1,productId);
		} catch (Exception e) {
			LOG.error("------------贷款产品申请出错!! params{custId="+cust.getCustId()+",productId="+productId+
					",otherParams="+ JacksonUtil.Obj2Json(otherParams) +"}", e);
			throw e;
		}
	}

	private void handlerExpireForAuthItemCheckResult(
			AuthItemCheckResultVo authItemCheckResult, Cust cust) throws Exception {
		List<Integer> expireAuthItemList = authItemCheckResult.getExpireAuthItemList();
		List<Long> expireSupplementItemList = authItemCheckResult.getExpireSupplementItemList();
		if(!Utility.isNullOrEmpty(expireAuthItemList)) {
			for (Integer itemCode : expireAuthItemList) {
				repositoryService.getStatus(itemCode + "", 1, cust);
			}
		}
		
		if(!Utility.isNullOrEmpty(expireSupplementItemList)) {
			for(Long id : expireSupplementItemList) {
				custSupplementItemService.resetItem(id);
			}
		}
	}

	/**
	 * 封装其他参数
	 * @author zhaoqi01
	 * @param otherParams
	 */
	public void packageOtherParams(Map<String, Object> otherParams, Cust cust, Long productId) {
		// 加入产品对应的枚举数据
		List<ProductEnum> allProductEnums = productEnumService.findAllList();
		List<ProductEnum> enumList = new ArrayList<ProductEnum>();
		for (ProductEnum productEnum : allProductEnums) {
			if(productEnum.getProductId().longValue() == productId.longValue()) {
				enumList.add(productEnum);
			}
		}
		otherParams.put("productEnums", enumList);
		
		// 加入Cust和 CustAccount
		CustAccount custAccount = new CustAccount();
		custAccount.setCustId(cust.getCustId());
		custAccount = custAccountService.find(custAccount).get(0);
		
		otherParams.put("cust", cust);
		otherParams.put("custAccount", custAccount);
		otherParams.put("productId", productId);
	}

	/**
	 * 处理申请结果
	 * @author zhaoqi01
	 * @param applyResult
	 * @throws BaseException 
	 */
	public void handlerProductApplyResult(ProductApplyResultVo applyResult, Cust cust, Long productId) throws BaseException {
		if(applyResult.getCode() == 0) { // 申请异常
			throw new BaseException(applyResult.getMsg());
		} 
		
		else if(applyResult.getCode() == 1) {
			CustProductApply custProductApply = custProductApplyService.findNewApplyProduct(productId, cust.getCustId());
			CustProductApply custProductApplyResult = applyResult.getCustProductApply();
			custProductApplyResult.setCustId(cust.getCustId());
			custProductApplyResult.setProductId(productId);
			if(custProductApplyResult.getIsApply() == null || custProductApplyResult.getIsApply()) {
				// 如果能再次申请，一定要设置下次申请时间
				custProductApplyResult.setIsApply(true);
				if(StringUtils.isBlank(custProductApplyResult.getCreditApplyTime()) ) {
					custProductApplyResult.setCreditApplyTime(ConcurrentDateUtil.formatDateTime(DateUtils.addDays(new Date(), -1)));
				}
			} else {
				custProductApplyResult.setCreditApplyTime("");
			}
			
			// rejectMsg长度判断，最大限制200字符
			String rejectMsg = custProductApplyResult.getRejectMsg();
			if(null != rejectMsg && rejectMsg.length() > 200) {
				custProductApplyResult.setRejectMsg(rejectMsg.substring(0, 200));
			}
			
			// 额度过期时间默认给30天
			if(StringUtil.isNullOrEmpty(custProductApplyResult.getCreditExpiretime())) {
				Date expiretDate = DateUtils.addDays(new Date(), 30);
				custProductApplyResult.setCreditExpiretime(ConcurrentDateUtil.formatDateTime(expiretDate));
			}
			
			if(custProductApply == null) {
				// 新增
				custProductApplyService.insert(custProductApplyResult);
			} else {
				// 更新
				custProductApplyResult.setApplyId(custProductApply.getApplyId());
				custProductApplyService.update(custProductApplyResult);
			}
			
//			try { //发送成功或失败短信，不影响主流程
//				CustAccount account = new CustAccount();
//				account.setCustId(cust.getCustId());
//
//				CustAccount  custAccount=custAccountService.find(account).get(0);
//				String mobile = custAccount.getUserName();
//				String appdesc=custAccount.getAppDesc();
//				String key=appdesc.split(";")[0].toString();
//				String productName=SmsDescEnum.getNameByAppDesc(key);
//				String userName=custAccount.getAccountRealname();
//
//				if(custProductApplyResult.getAuditResult() == 1){
//					sMSMessageManager.sendCreditSuccess(mobile,productName,userName);
//				}else if (custProductApplyResult.getAuditResult() == 0){
//					sMSMessageManager.sendCreditFail(mobile,productName,userName);
//				}
//			} catch (Exception e) {
//
//			}
			
			// 插入申请日志数据
			CustProductApplyRecord record = new CustProductApplyRecord();
			BeanUtil.copy(custProductApplyResult, record);
			record.setApplyId(null);
			custProductApplyRecordService.saveCustProductApplyRecord(record);
		}
	}
	/**
	 * 根据产品id获取授信结果
	 * @param productId
	 * @throws Exception
	 */
	@Log
	public void getProductApplyResult(long productId) throws Exception{
		CustProductApply custProductApply = new CustProductApply();
		custProductApply.setProductId(productId);
		custProductApply.setAuditResult(2);  
		//根据产品id查找所有状态为审核中的记录
		List<CustProductApply> list = custProductApplyService.findByConditions(custProductApply);
		for(CustProductApply apply : list){			
			try {
				Cust cust = custService.findById(apply.getCustId());
				CustProductApply result = this.getProductApplyResultServiceImpl(productId).getProductApplyResult(cust, productId);
				result.setApplyId(apply.getApplyId());
				if(StringUtils.isEmpty(result.getRejectMsg())) {
					continue;
				}
				custProductApplyService.update(result);
				try { //发送成功或失败短信，不影响主流程
					CustAccount account = new CustAccount();
					account.setCustId(cust.getCustId());
					
					CustAccount  custAccount=custAccountService.find(account).get(0);
					
					String mobile = custAccount.getUserName();
					String appdesc=custAccount.getAppDesc();		
					String key=appdesc.split(";")[0].toString();	
					String productName=SmsDescEnum.getNameByAppDesc(key);
					String userName=custAccount.getAccountRealname();
					
					if(result.getAuditResult() == 1){
						sMSMessageManager.sendCreditSuccess(mobile,productName,userName);
					}else if (result.getAuditResult() == 0){
						sMSMessageManager.sendCreditFail(mobile,productName,userName);
					}				
				} catch (Exception e) {
					
				}
			} catch (Exception e) {
				LOG.error("获取授信结果", e);
				continue;
			}
		}
	}
	
}
